package view;

import javax.swing.*;
import javax.sound.sampled.*;

import ds.SkillTree;
import model.Map;
import model.Pacman;
import model.Ghost;
import model.UndoStack;
import model.Leaderboard;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;

public class GamePanel extends JPanel implements ActionListener, KeyListener {
    private static final long serialVersionUID = 12345L;
	private Timer timer;
    private Map map;
    private Pacman pacman;
    private PacmanView pacmanView;
    private MapView mapView;
    private List<Ghost> ghosts = new ArrayList<>();
    private List<GhostView> ghostViews = new ArrayList<>();
    private LeaderboardView leaderboardView;
    private SkillTreeView skillTreeView;
    private UndoStack undoStack;
    private Leaderboard leaderboard;
    private SkillTree skillTree;
    private int ghostMoveCounter = 0;
    private int ghostMoveInterval = 3; // 幽灵每3帧移动一次
    private boolean gameOver = false;
    private int score = 0;
    private Clip eatClip; // 用于控制吃豆子音效
    private Clip bgmClip; // 背景音乐

    public GamePanel() {
        setFocusable(true);
        setBackground(Color.BLACK);
        setPreferredSize(new Dimension(800, 900));
        addKeyListener(this);
        map = new Map();
        pacman = new Pacman(1, 1);
        pacmanView = new PacmanView(pacman);
        mapView = new MapView(map);
        ghosts.add(new Ghost(10, 10, "images/ghost1.png"));
        ghosts.add(new Ghost(10, 9, "images/ghost2.png"));
        ghosts.add(new Ghost(11, 10, "images/ghost3.png"));
        ghosts.add(new Ghost(11, 9, "images/ghost4.png"));
        for (Ghost ghost : ghosts) {
            ghostViews.add(new GhostView(ghost));
        }
        leaderboard = new Leaderboard();
        leaderboardView = new LeaderboardView(leaderboard);
        skillTree = new SkillTree();
        skillTreeView = new SkillTreeView(skillTree);
        undoStack = new UndoStack();
        // 遍历MyTree并打印所有技能名（示例）
        java.util.List<SkillTree.Skill> allSkills = skillTree.getTree().traverse();
        for (SkillTree.Skill skill : allSkills) {
            System.out.println("技能树节点: " + skill.name);
        }
        timer = new Timer(100, this);
        timer.start();
        playBgm(); // 启动时播放背景音乐
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        mapView.draw(g);
        pacmanView.draw(g, Map.TILE_SIZE);
        for (GhostView gv : ghostViews) {
            gv.draw(g, Map.TILE_SIZE);
        }
        leaderboardView.draw(g, Map.COLS * Map.TILE_SIZE + 30, 80, score);
        skillTreeView.draw(g, getWidth(), Map.COLS * Map.TILE_SIZE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (gameOver) return;
        // 幽灵每ghostMoveInterval帧才移动一次
        ghostMoveCounter++;
        if (ghostMoveCounter >= ghostMoveInterval) {
            for (int i = 0; i < ghosts.size(); i++) {
                Ghost ghost = ghosts.get(i);
                int targetRow = pacman.getRow();
                int targetCol = pacman.getCol();
                if (i == 1) { // 粉色，追Pacman前方4格
                    int[] front = pacman.getFront(4, map);
                    targetRow = front[0];
                    targetCol = front[1];
                } else if (i == 2) { // 蓝色，追Pacman和红幽灵的中点
                    Ghost red = ghosts.get(0);
                    targetRow = (pacman.getRow() + red.row) / 2;
                    targetCol = (pacman.getCol() + red.col) / 2;
                } else if (i == 3) { // 橙色，远追Pacman，近追左下角
                    int dist = Math.abs(ghost.row - pacman.getRow()) + Math.abs(ghost.col - pacman.getCol());
                    if (dist > 8) {
                        targetRow = pacman.getRow();
                        targetCol = pacman.getCol();
                    } else {
                        targetRow = map.getRows() - 2;
                        targetCol = 1;
                    }
                }
                ghost.moveBFS(map, targetRow, targetCol);
            }
            ghostMoveCounter = 0;
        }
        // 检查Pacman是否被幽灵吃掉
        for (Ghost ghost : ghosts) {
            if (ghost.row == pacman.getRow() && ghost.col == pacman.getCol()) {
                gameOver = true;
                timer.stop();
                showGameOverDialog();
                break;
            }
        }
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (gameOver) return;
        if (e.getKeyCode() == KeyEvent.VK_Z) {
            int[] pos = undoStack.pop();
            if (pos != null) {
                pacman.setPosition(pos[0], pos[1]);
                repaint();
            }
        } else {
            pacman.setDirection(e.getKeyCode());
            // Pacman每次按键只移动一步
            undoStack.push(pacman.getRow(), pacman.getCol());
            int oldRow = pacman.getRow();
            int oldCol = pacman.getCol();
            boolean ateDot = pacman.move(map);
            if (ateDot) {
                score += 10;
                playEatSound();
            }
            if (pacman.getRow() != oldRow || pacman.getCol() != oldCol) {
                repaint();
            }
            // 检查Pacman是否被幽灵吃掉
            for (Ghost ghost : ghosts) {
                if (ghost.row == pacman.getRow() && ghost.col == pacman.getCol()) {
                    gameOver = true;
                    timer.stop();
                    showGameOverDialog();
                    break;
                }
            }
            repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {}
    @Override
    public void keyTyped(KeyEvent e) {}

    public void showGameOverDialog() {
        if (bgmClip != null && bgmClip.isRunning()) {
            bgmClip.stop();
            bgmClip.close();
        }
        SwingUtilities.invokeLater(() -> {
            int option = JOptionPane.showOptionDialog(this,
                    "游戏结束！你被幽灵吃掉了。",
                    "游戏结束",
                    JOptionPane.DEFAULT_OPTION,
                    JOptionPane.INFORMATION_MESSAGE,
                    null,
                    new Object[]{"重新开始", "退出"},
                    "重新开始");
            if (option == 0) {
                restartGame();
            } else {
                System.exit(0);
            }
        });
    }

    private void restartGame() {
        // 重新初始化游戏状态
        leaderboard.addScore(score); // 游戏结束时保存分数
        score = 0;
        map = new Map();
        pacman = new Pacman(1, 1);
        pacmanView = new PacmanView(pacman);
        mapView = new MapView(map);
        ghosts.clear();
        ghostViews.clear();
        ghosts.add(new Ghost(10, 10, "images/ghost1.png"));
        ghosts.add(new Ghost(10, 9, "images/ghost2.png"));
        ghosts.add(new Ghost(11, 10, "images/ghost3.png"));
        ghosts.add(new Ghost(11, 9, "images/ghost4.png"));
        for (Ghost ghost : ghosts) {
            ghostViews.add(new GhostView(ghost));
        }
        undoStack = new UndoStack();
        skillTree = new SkillTree();
        ghostMoveCounter = 0;
        gameOver = false;
        timer.start();
        if (bgmClip != null && bgmClip.isRunning()) {
            bgmClip.stop();
            bgmClip.close();
        }
        playBgm(); // 重新开始时重新播放背景音乐
        repaint();
    }

    private void playBgm() {
        try {
            if (bgmClip != null && bgmClip.isRunning()) {
                bgmClip.stop();
                bgmClip.close();
            }
            AudioInputStream audioIn = AudioSystem.getAudioInputStream(new java.io.File("sounds/bgm.wav"));
            bgmClip = AudioSystem.getClip();
            bgmClip.open(audioIn);
            bgmClip.loop(Clip.LOOP_CONTINUOUSLY); // 循环播放
            bgmClip.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void playEatSound() {
        // Implementation of playEatSound method
    }
} 